package com.sunshine.lnuplus.utils

import android.annotation.SuppressLint
import android.content.ContentUris
import android.content.ContentValues
import android.content.Context
import android.database.Cursor
import android.graphics.Color
import android.net.Uri
import android.os.Looper
import android.provider.CalendarContract
import com.sunshine.lnuplus.model.InitData
import com.sunshine.lnuplus.model.room.CountDown
import com.sunshine.lnuplus.view.DialogWithView
import es.dmoral.toasty.Toasty
import java.text.SimpleDateFormat
import java.util.*

/**
 * Created by sunshine on 2020/3/7
 * 添加日历账户参考
 * https://www.jianshu.com/p/4820e02b2ee4
 */
object CalenderUtils {

    private lateinit var context: Context
    private const val CALENDER_EVENT_URL = "content://com.android.calendar/events"
    private const val CALENDER_REMINDER_URL = "content://com.android.calendar/reminders"
    private const val CALENDER_URL = "content://com.android.calendar/calendars"
    private const val CALENDARS_NAME = "boohee"
    private const val CALENDARS_ACCOUNT_NAME = "lnuplus@sunshine.com"
    private const val CALENDARS_ACCOUNT_TYPE = "com.android.lnuplus"
    private const val CALENDARS_DISPLAY_NAME = "LNUPLUS账户"

    fun initLesson(
        context: Context,
        time: Int,
        loading: DialogWithView
    ){
        this.context = context
        val thisWeek = DateUtils.getThisWeek(InitData.lessonStyle.startMonth, InitData.lessonStyle.startDay)
        val dateFormat = SimpleDateFormat("MM/dd")

        for(week in thisWeek..InitData.lessonStyle.weekCount){
            InitData.lessonList?.forEach {
                if(it.weeks.contains(week)){
                    val beginDate = Date()
                    val calendar = Calendar.getInstance()
                    calendar.time = beginDate
                    calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + (it.dayOfWeek - DateUtils.getTodayOfWeek() + 7 * (week - thisWeek)))
                    val endDate = dateFormat.parse(dateFormat.format(calendar.time))
                    try {
                        val startHour: Int
                        val startMin: Int
                        val endHour: Int
                        val endMin: Int
                        val start = InitData.lessonStyle.lessonTime[it.start - 1].split("\n")[0].split(":")
                        val end = InitData.lessonStyle.lessonTime[it.end - 1].split("\n")[1].split(":")
                        startHour = start[0].toInt()
                        startMin = start[1].toInt()
                        endHour = end[0].toInt()
                        endMin = end[1].toInt()

                        addToCalender(DateUtils.year,
                            dateFormat.format(endDate).split("/")[0].toInt() - 1,
                            dateFormat.format(endDate).split("/")[1].toInt(),
                            startHour,
                            startMin,
                            endHour,
                            endMin,
                            it.lessonName,
                            it.location,
                            time,
                            "辽大+课表")
                    }catch (e: Exception){
                        loading.dismiss()
                        Looper.prepare()
                        Toasty.error(context, "请先为第${it.start}-${it.end}节设置时间")
                        Looper.loop()
                        return
                    }

                }
            }
        }
        Looper.prepare()
        loading.dismiss()
        Toasty.success(context, "添加成功，快去日历中看看吧~").show()
        Looper.loop()
    }

    fun initCountDown(
        context: Context,
        time: Int,
        loading: DialogWithView,
        countDownList: List<CountDown>
    ) {
        this.context = context
        val thisWeek = DateUtils.getThisWeek(InitData.lessonStyle.startMonth, InitData.lessonStyle.startDay)
        val simpleFormat = SimpleDateFormat("yyyy-MM-dd hh:mm")
        val dateFormat = SimpleDateFormat("yyyy-MM-dd-hh-mm")
        countDownList.forEach {
            if(it.time != "" && DateUtils.getCountDownTime(it.time) >= 0){
                val dateString = dateFormat.format(simpleFormat.parse(it.time)).split("-")
                try {
                    addToCalender(dateString[0].toInt(),
                        dateString[1].toInt() - 1,
                        dateString[2].toInt(),
                        dateString[3].toInt(),
                        dateString[4].toInt(),
                        dateString[3].toInt() + 1,
                        dateString[4].toInt(),
                        it.lessonName,
                        it.location,
                        time,
                        "辽大+倒计时")
                }catch (e: Exception){
                    loading.dismiss()
                    Looper.prepare()
                    Toasty.error(context, "导出${it.lessonName}时出现问题")
                    Looper.loop()
                    return
                }
            }
        }

        Looper.prepare()
        loading.dismiss()
        Toasty.success(context, "添加成功，快去日历中看看吧~").show()
        Looper.loop()
    }

    @SuppressLint("MissingPermission")
    private fun addToCalender(
        year: Int,
        month: Int,
        date: Int,
        beginHour: Int,
        beginMin: Int,
        endHour: Int,
        endMin: Int,
        className: String,
        classRoom: String,
        remider: Int,
        s: String
    ){
        val calID = checkAndAddCalendarAccount(context)
        var startMillis: Long
        var endMillis: Long
        val beginTime = Calendar.getInstance()
        beginTime.set(year, month, date, beginHour, beginMin)//注意，月份的下标是从0开始的
        startMillis = beginTime.timeInMillis //插入日历时要取毫秒计时
        val endTime = Calendar.getInstance()
        endTime.set(year, month, date, endHour, endMin)
        endMillis = endTime.timeInMillis
        val eValues = ContentValues() //插入事件
        val rValues = ContentValues() //插入提醒，与事件配合起来才有效
        val tz = TimeZone.getDefault() //获取默认时区
        //插入日程
        eValues.put(CalendarContract.Events.DTSTART, startMillis)
        eValues.put(CalendarContract.Events.DTEND, endMillis)
        eValues.put(CalendarContract.Events.TITLE, className)
        eValues.put(CalendarContract.Events.DESCRIPTION, s)
        eValues.put(CalendarContract.Events.CALENDAR_ID, calID)
        eValues.put(CalendarContract.Events.EVENT_LOCATION, classRoom)
        eValues.put(CalendarContract.Events.EVENT_TIMEZONE, tz.id)

        val uri: Uri? = context.contentResolver.insert(CalendarContract.Events.CONTENT_URI, eValues)
        //插完日程之后必须再插入以下代码段才能实现提醒功能
        if (remider != 0) {
            val myEventsId = uri?.lastPathSegment // 得到当前表的_id
            rValues.put("event_id", myEventsId)
            rValues.put("minutes", remider) //提前remider分钟提醒
            rValues.put("method", 1) //如果需要有提醒,必须要有这一行
            context.contentResolver.insert(Uri.parse(CALENDER_REMINDER_URL), rValues)
        }
    }


    /**
     * 删除日历事件
     */
    fun deleteCalendarEvent(
        context: Context,
        loading: DialogWithView,
        s: String
    ) {
        val eventCursor: Cursor? = context.contentResolver.query(Uri.parse(CALENDER_EVENT_URL), null, null, null, null)
        eventCursor.use { eventCursor ->
            if (eventCursor == null) { //查询返回空值
                loading.dismiss()
                return
            }
            if (eventCursor.count > 0) {
                eventCursor.moveToFirst()
                while (!eventCursor.isAfterLast) {
                    val description: String? =
                        eventCursor.getString(eventCursor.getColumnIndex("description"))
                    if (description == s) {
                        val id: Int =
                            eventCursor.getInt(eventCursor.getColumnIndex(CalendarContract.Calendars._ID)) //取得id
                        val deleteUri = ContentUris.withAppendedId(
                            Uri.parse(CALENDER_EVENT_URL),
                            id.toLong()
                        )
                        val rows = context.contentResolver.delete(deleteUri, null, null)
                        if (rows == -1) { //事件删除失败
                            Looper.prepare()
                            Toasty.error(context, "删除失败").show()
                            loading.dismiss()
                            Looper.loop()
                            return
                        }
                    }
                    eventCursor.moveToNext()
                }
            }
            Looper.prepare()
            loading.dismiss()
            Toasty.success(context, "删除成功~").show()
            Looper.loop()
        }
    }

    /**
     * 检查是否已经添加了日历账户，如果没有添加先添加一个日历账户再查询
     * 获取账户成功返回账户id，否则返回-1
     */
    private fun checkAndAddCalendarAccount(context: Context): Int {
        val oldId = checkCalendarAccount(context)
        return if (oldId >= 0) {
            oldId
        } else {
            val addId = addCalendarAccount(context)
            if (addId >= 0) {
                checkCalendarAccount(context)
            } else {
                -1
            }
        }
    }

    /**
     * 检查是否存在现有账户，存在则返回账户id，否则返回-1
     */
    private fun checkCalendarAccount(context: Context): Int {
        val userCursor = context.contentResolver
            .query(Uri.parse(CALENDER_URL), null, null, null, null)
        return userCursor.use { userCursor ->
            if (userCursor == null) { //查询返回空值
                return -1
            }
            val count = userCursor.count
            if (count > 0) { //存在现有账户，取第一个账户的id返回
                userCursor.moveToFirst()
                userCursor.getInt(userCursor.getColumnIndex(CalendarContract.Calendars._ID))
            } else {
                -1
            }
        }
    }

    /**
     * 添加日历账户，账户创建成功则返回账户id，否则返回-1
     */
    private fun addCalendarAccount(context: Context): Long {
        val timeZone = TimeZone.getDefault()
        val value = ContentValues()
        value.put(CalendarContract.Calendars.NAME, CALENDARS_NAME)
        value.put(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME)
        value.put(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE)
        value.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CALENDARS_DISPLAY_NAME)
        value.put(CalendarContract.Calendars.VISIBLE, 1)
        value.put(CalendarContract.Calendars.CALENDAR_COLOR, Color.BLUE)
        value.put(
            CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL,
            CalendarContract.Calendars.CAL_ACCESS_OWNER
        )
        value.put(CalendarContract.Calendars.SYNC_EVENTS, 1)
        value.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, timeZone.id)
        value.put(CalendarContract.Calendars.OWNER_ACCOUNT, CALENDARS_ACCOUNT_NAME)
        value.put(CalendarContract.Calendars.CAN_ORGANIZER_RESPOND, 0)
        var calendarUri = Uri.parse(CALENDER_URL)
        calendarUri = calendarUri.buildUpon()
            .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
            .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME)
            .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE)
            .build()
        val result = context.contentResolver.insert(calendarUri, value)
        return if (result == null) -1 else ContentUris.parseId(result)
    }


}